home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
154_01
/
xref.c
< prev
next >
Wrap
Text File
|
1980-01-01
|
4KB
|
185 lines
/*
* xref.c: word-to-line cross-reference -
* usage: xref [file] (defaults to standard input)
* note: A "word" is defined by the macro "okchar(c)"
*
* (c) Chuck Allison, 1985
*
*/
#include <stdio.h>
#include <ctype.h>
#ifdef MICROSOFT
#include <malloc.h>
#define getmem malloc
#define chk_ferror fprintf
#endif
#define okchar(c) (isalnum(c) || c == '-' || c == '\'')
#define MAXLINE 512
/* ..Linked-list structure for each list of line numbers.. */
struct list
{
struct list *next;
int lnum;
} *addline();
/* ..Node structure for tree of distinct words.. */
struct tree
{
char *word;
struct tree *left,*right;
struct list *lptr; /* -> to list of line #'s for this word */
} *words = NULL, *node, *addword(), *find_node();
char *lineptr, *getword(), *getmem();
int distinct = 0;
main(argc,argv)
int argc;
char *argv[];
{
register lineno = 0;
static char linebuf[MAXLINE], wordbuf[MAXLINE];
/* ..Get optional filename.. */
if (argc > 1)
if (freopen(argv[1],"r",stdin) == NULL)
{
printf("---> ERROR: can't open %s\n",argv[1]);
exit(1);
}
else
fputs("reading file ...\n",stderr);
else
fputs("Enter data:\n\n",stderr);
/* ..Process each line of text file.. */
while (fgets(linebuf,MAXLINE,stdin))
{
++lineno; /* ..we just read another line.. */
lineptr = linebuf; /* ..point to start of line.. */
while (getword(wordbuf))
{
/* ..add to tree.. */
words = addword(words,wordbuf);
/* ..get list header for this word's line numbers.. */
node = find_node(words,wordbuf);
/* ..add this line to list of line numbers.. */
node->lptr = addline(node->lptr,lineno);
}
}
fprintf(stderr,"No. of distinct words: %d\n\n",distinct);
print_tree(words);
}
char *getword(s) /* ..get next word from line buffer.. */
char *s;
{
register char *wordptr = s;
/* ..Ignore unwanted characters.. */
while (*lineptr && !okchar(*lineptr))
++lineptr;
/* ..Build word.. */
while (okchar(*lineptr))
{
*wordptr++ = tolower(*lineptr);
lineptr++;
};
*wordptr = '\0';
return strlen(s) ? s : NULL;
}
struct tree *addword(t,word) /* ..add word to list (if new).. */
struct tree *t;
char *word;
{
if (t == NULL)
{
/* ..new entry.. */
++distinct;
t = (struct tree *) getmem(sizeof(struct tree));
t->word = (char *) getmem((strlen(word)+1)*sizeof(char));
strcpy(t->word,word);
t->left = t->right = (struct tree *) NULL;
t->lptr = (struct list *) NULL;
}
else if (strcmp(t->word,word) < 0)
t->right = addword(t->right,word);
else if (strcmp(t->word,word) > 0)
t->left = addword(t->left,word);
return t;
}
struct list *addline(p,n) /* ..add line # for current word.. */
struct list *p;
int n;
{
struct list *q;
if (p == NULL)
{
/* ..insert at tail.. */
q = (struct list *) getmem(sizeof(struct list));
q->lnum = n;
q->next = (struct list *) NULL;
return q;
}
else if (p->lnum != n)
/* ..keep looking.. */
p->next = addline(p->next,n);
return p;
}
print_tree(t)
struct tree *t;
{
if (t != NULL)
{
print_tree(t->left);
printf("%-20.20s: ",t->word);
chk_ferror(stdout,"standard output");
print_list(t->lptr); putchar('\n');
print_tree(t->right);
}
}
print_list(p)
struct list *p;
{
register count;
for (count = 0; p != NULL; p = p->next, ++count)
{
printf("%5d",p->lnum);
if ((count+1)%10 == 0 && p->next != NULL)
printf("\n%22c",' ');
}
}
struct tree *find_node(p,s)
struct tree *p;
char *s;
{
if (strcmp(p->word,s) > 0)
return find_node(p->left,s);
else if (strcmp(p->word,s) < 0)
return find_node(p->right,s);
else
return p; /* .."s" is guaranteed to be found.. */
}